package com.hivekion.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hivekion.common.core.SystemConstant;
import com.hivekion.common.entity.TreeNode;
import com.hivekion.common.exception.BusinessException;
import com.hivekion.common.redis.RedisUtil;
import com.hivekion.system.domain.SysStatisticsItem;
import com.hivekion.system.domain.vo.SysStatisticsItemCreateInputVo;
import com.hivekion.system.domain.vo.SysStatisticsItemUpdateInputVo;
import com.hivekion.system.domain.vo.SysStatisticsItemViewVo;
import com.hivekion.system.mapper.SysStatisticsItemMapper;
import com.hivekion.system.service.ISysStatisticsItemService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysStatisticsItemServiceImpl implements ISysStatisticsItemService {

      @Autowired
      private SysStatisticsItemMapper itemMapper;

      @Autowired
      private RedisUtil redisUtil;

      @Override
      public Boolean checkItemNameUnique(String itemName, String itemId) {
	    LambdaQueryWrapper<SysStatisticsItem> StatisticsItemLambdaQueryWrapper =
		    Wrappers.lambdaQuery();
	    StatisticsItemLambdaQueryWrapper.eq(SysStatisticsItem::getName, itemName);
	    if (StringUtils.isNotEmpty(itemName)) {
		  StatisticsItemLambdaQueryWrapper.eq(SysStatisticsItem::getId, itemName);
	    }
	    List<SysStatisticsItem> list = itemMapper.selectList(StatisticsItemLambdaQueryWrapper);
	    return list.size() > 0;
      }

      @Override
      public boolean create(SysStatisticsItemCreateInputVo inputVo) {
	    SysStatisticsItem item = new SysStatisticsItem();
	    BeanUtils.copyProperties(inputVo, item);
	    if (inputVo.getParentId() == null) {
		  item.setParentId("");
	    }
	    boolean bl = itemMapper.insert(item) > 0;
	    if (bl) this.updateRedis();
	    return bl;
      }

      @Override
      public boolean update(SysStatisticsItemUpdateInputVo inputVo) {
	    SysStatisticsItem item = itemMapper.selectById(inputVo.getId());
	    if (item == null) {
		  throw new BusinessException(500, "统计项不存在！");
	    }
	    BeanUtils.copyProperties(inputVo, item);
	    if (inputVo.getParentId() == null) {
		  item.setParentId("");
	    }
	    boolean bl = itemMapper.updateById(item) > 0;
	    if (bl) this.updateRedis();
	    return bl;
      }

      @Override
      public boolean delete(String StatisticsItemId) {
	    List<SysStatisticsItem> children = getChildren(StatisticsItemId);
	    if (children.size() > 0) {
		  throw new BusinessException(500, "该统计项下还有统计项");
	    }
	    boolean bl = itemMapper.deleteById(StatisticsItemId) > 0;
	    if (bl) this.updateRedis();
	    return bl;
      }

      @Override
      public SysStatisticsItem getInfo(String itemId) {
	    SysStatisticsItem item = itemMapper.selectById(itemId);
	    if (item == null) {
		  throw new BusinessException(500, "未找到统计项信息");
	    }
	    return item;
      }

      @Override
      public List<SysStatisticsItem> getItemListByList(List<String> itemList) {

	    LambdaQueryWrapper<SysStatisticsItem> StatisticsItemLambdaQueryWrapper =
		    Wrappers.lambdaQuery();

	    for (String itemId : itemList) {
		  StatisticsItemLambdaQueryWrapper.eq(SysStatisticsItem::getId, itemId).or();
	    }

	    List<SysStatisticsItem> sysStatisticsItems =
		    itemMapper.selectList(StatisticsItemLambdaQueryWrapper);

	    return sysStatisticsItems;
      }

      @Override
      public List<SysStatisticsItemViewVo> getList() {
	    return buildViewVo(getParentItems());
      }

      private List<SysStatisticsItemViewVo> buildViewVo(List<SysStatisticsItem> list) {
	    List<SysStatisticsItemViewVo> nodes = new ArrayList<>();
	    if (list != null && list.size() > 0) {
		  list.forEach(
			  StatisticsItem -> {
				SysStatisticsItemViewVo vo = new SysStatisticsItemViewVo();
				BeanUtils.copyProperties(StatisticsItem, vo);

				vo.setChildren(null);
				List<SysStatisticsItemViewVo> vos = getChilderenVo(StatisticsItem.getId());
				if (vos != null && vos.size() > 0) {
				      vo.setChildren(vos);
				}
				nodes.add(vo);
			  });
	    }
	    return nodes;
      }

      public List<SysStatisticsItemViewVo> getChilderenVo(String parentId) {
	    List<SysStatisticsItem> list = getChildren(parentId);
	    return buildViewVo(list);
      }

      /*
       * redis 缓存数据
       * */
      @Override
      public List<SysStatisticsItem> getAllList() {
	    if (redisUtil.hasKey(SystemConstant.redis_item_data)) {
		  List<SysStatisticsItem> list =
			  JSON.parseArray(
				  redisUtil.get(SystemConstant.redis_item_data).toString(),
				  SysStatisticsItem.class);
		  return list;
	    } else {
		  List<SysStatisticsItem> allItem = itemMapper.selectList(null);
		  redisUtil.set(SystemConstant.redis_item_data, JSON.toJSONString(allItem));
		  return allItem;
	    }
      }

      private void updateRedis() {
	    List<SysStatisticsItem> allItem = itemMapper.selectList(null);
	    redisUtil.set(SystemConstant.redis_item_data, JSON.toJSONString(allItem));
      }

      @Override
      public List<TreeNode> getTreeSelect() {
	    List<TreeNode> treeNodes = buildTreeNode(getParentItems());
	    return treeNodes;
      }

      private List<SysStatisticsItem> getParentItems() {
	    List<SysStatisticsItem> parentItems =
		    this.getAllList().stream()
			    .filter(x -> StringUtils.isEmpty(x.getParentId()))
			    .sorted(Comparator.comparing(SysStatisticsItem::getSortCode))
			    .collect(Collectors.toList());
	    return parentItems;
      }

      private List<TreeNode> buildTreeNode(List<SysStatisticsItem> list) {
	    List<TreeNode> treeNodes = new ArrayList<>();
	    if (list != null && list.size() > 0) {
		  list.forEach(
			  item -> {
				TreeNode node = new TreeNode(item.getId(), item.getName(), item.getId());
				node.setData(item);
				List<TreeNode> children = this.getChildrenNode(item.getId());
				if (children != null && children.size() > 0) {
				      node.setLeaf(false);
				      node.setChildren(children);
				} else {
				      node.setLeaf(true);
				}
				treeNodes.add(node);
			  });
	    }
	    return treeNodes;
      }

      private List<TreeNode> getChildrenNode(String parentId) {
	    List<SysStatisticsItem> list = getChildren(parentId);
	    return buildTreeNode(list);
      }

      private List<SysStatisticsItem> getChildren(String parentId) {
	    LambdaQueryWrapper<SysStatisticsItem> itemLambdaQueryWrapper = Wrappers.lambdaQuery();
	    itemLambdaQueryWrapper.eq(SysStatisticsItem::getParentId, parentId);
	    List<SysStatisticsItem> allList = this.getAllList();
	    List<SysStatisticsItem> list =
		    allList.stream()
			    .filter(t -> parentId.equals(t.getParentId()))
			    .sorted(Comparator.comparing(SysStatisticsItem::getSortCode))
			    .collect(Collectors.toList());
	    return list;
      }

      private SysStatisticsItem getItem(String itemId) {
	    SysStatisticsItem item = itemMapper.selectById(itemId);
	    if (item == null) {
		  throw new BusinessException(500, "未找到部门信息");
	    }
	    return item;
      }
}
